package com.fzy.springsecurity2.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

/**
 * @author fzy
 * @version 1.0
 * 创建时间：2024-10-13 21:17
 */

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        // 创建 ObjectMapper
        // 配置按顺序执行，不能随意调换顺序
        ObjectMapper objectMapper = Jackson2ObjectMapperBuilder
                .json()
                .featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)  // 关闭json有，但pojo没有对应属性时的异常
                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // 关闭某个特征
                .featuresToDisable(MapperFeature.AUTO_DETECT_GETTERS)       // 禁用自动检测 getter
                .featuresToDisable(MapperFeature.AUTO_DETECT_IS_GETTERS)    // 禁用 is 类型的 getter
                .featuresToDisable(MapperFeature.USE_GETTERS_AS_SETTERS)    // 禁用 getter 作为 setter
                .featuresToEnable(MapperFeature.AUTO_DETECT_FIELDS)         // 启用自动检测字段
                .indentOutput(true) // 美化格式
                .serializationInclusion(JsonInclude.Include.NON_NULL) // 不为 null 才序列化
                //.visibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)  // 可见性，不序列化任何字段
                .visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY) // 可见性，只序列化任意修饰符的字段
                .build();

        // 启用自动包含类型信息，用于反序列化时重建对象的实际类型
        //objectMapper.activateDefaultTyping(
        //        objectMapper.getPolymorphicTypeValidator(),  //  验证器，用于验证实际要反序列化的子类型是否有效
        //        ObjectMapper.DefaultTyping.NON_FINAL, // 定义哪些类型的对象需要添加额外的类型信息，NON_FINAL：非 final类都会包含
        //        JsonTypeInfo.As.PROPERTY);    // 类型信息的包含方式 PROPERTY：类型信息作为JSON对象的一个属性

        return objectMapper;
    }
}
